package com.app.stick.factory;/**
 * @program: app-admin
 * @name MonitorFactory
 * @description: 时间监测
 */

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import com.app.common.constant.CacheConstants;
import com.app.common.core.redis.RedisCache;
import com.app.common.enums.DeleteEnum;
import com.app.common.enums.sick.MonitorTypeEnum;
import com.app.common.enums.sick.NoticeTypeEnum;
import com.app.common.enums.sick.PdiBindStatusEnum;
import com.app.common.utils.StringUtils;
import com.app.common.utils.spring.SpringUtils;
import com.app.common.utils.uuid.IdUtils;
import com.app.framework.manager.AsyncManager;
import com.app.stick.bind.domain.BizPatientDeviceInfo;
import com.app.stick.bind.mapper.BizPatientDeviceInfoMapper;
import com.app.stick.monitor.domain.vo.BizMonitorCacheVo;
import com.app.websocket.server.MonitorWebSocketServer;
import com.app.websocket.server.NoticeWebSocketServer;
import com.app.websocket.vo.DeviceMonitorVo;
import com.app.websocket.vo.NoticeMessageVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 *@author:
 *@program: app-admin
 *@name MonitorFactory
 *@description: 时间监测
 */
@Slf4j
public class MonitorFactory {

    /**
     * A5 03 09 3E 0D 23 E5 FF A2 79 53 30 AA
     * A5   针头
     * 03 	0XFF：传感器没接/断开 0X00：传感器短路 0X01：温度<25° 0X02：温度>45° 0X03: 环境温度<5° 0x04: 环境温度>40°
     * 09 数据位
     * 3E 0D 温度
     * 23 E5 FF A2 79 53
     * 30  电量
     * AA  结束位
     * 实时监测指令信息
     * @param command
     * @return {@link TimerTask}
     */
    public static TimerTask monitor(String command) {
        return new TimerTask() {
            @Override
            public void run() {
                if (command.length() == 26) {
                    //获取数据类型
                    String msgType = command.substring(2, 4);
                    //获取温度
                    String temperatureBefore = command.substring(8, 10);
                    String temperatureAfter = command.substring(6, 8);
                    int conversionTemperature = HexUtil.hexToInt(temperatureBefore + temperatureAfter);
                    double temperature = NumberUtil.div(conversionTemperature, 100, 1);
                    //获取电量
                    String hexElectricity = command.substring(22, 24);
                    int electricity = HexUtil.hexToInt(hexElectricity);
                    log.info("获取到的指令msgType:{}, temperature:{}, electricity:{}", msgType, temperature, electricity);

                    BizPatientDeviceInfoMapper bizPatientDeviceInfoMapper = SpringUtils.getBean(BizPatientDeviceInfoMapper.class);
                    BizPatientDeviceInfo bizPatientDeviceInfo = bizPatientDeviceInfoMapper.selectOne(new LambdaQueryWrapper<BizPatientDeviceInfo>()
                            .eq(BizPatientDeviceInfo::getDeviceCode, "000001")
                            .eq(BizPatientDeviceInfo::getPdiBindStatus, PdiBindStatusEnum.BIND.getCode())
                            .eq(BizPatientDeviceInfo::getDelFlag, DeleteEnum.NO.getCode()));
                    if (StringUtils.isNotNull(bizPatientDeviceInfo)) {
                        RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
                        BizMonitorCacheVo cacheVo = redisCache.getCacheObject(CacheConstants.DEVICE_MONITOR_KEY + bizPatientDeviceInfo.getDeviceCode());
                        if (StringUtils.isNull(cacheVo)) {
                            cacheVo = new BizMonitorCacheVo();
                            cacheVo.setDeviceCode(bizPatientDeviceInfo.getDeviceCode());
                            cacheVo.setPdiId(bizPatientDeviceInfo.getPdiId());
                            cacheVo.setVisitId(bizPatientDeviceInfo.getVisitId());
                            cacheVo.setMonitorFirstDate(new Date());
                            cacheVo.setMonitorEndDate(new Date());
                            cacheVo.setPmiElectricity(electricity);
                            cacheVo.setPmiTemperature(temperature);
                        } else {
                            cacheVo.setMonitorEndDate(new Date());
                            cacheVo.setPmiElectricity(electricity);
                            cacheVo.setPmiTemperature(temperature);
                        }
                        redisCache.setCacheObject(CacheConstants.DEVICE_MONITOR_KEY + bizPatientDeviceInfo.getDeviceCode(), cacheVo);

                        DeviceMonitorVo monitorVo = new DeviceMonitorVo();
                        monitorVo.setVisitId(bizPatientDeviceInfo.getVisitId());
                        monitorVo.setPdiId(bizPatientDeviceInfo.getPdiId());
                        monitorVo.setDeviceCode(bizPatientDeviceInfo.getDeviceCode());
                        monitorVo.setMonitorType(msgType);
                        monitorVo.setPmiElectricity(electricity);
                        monitorVo.setPmiTemperature(temperature);
                        monitorVo.setPmiTime(cacheVo.getMonitorEndDate());
                        monitorVo.setPmiDuration(cacheVo.getIntervalSeconds());
                        MonitorWebSocketServer.sendSelfMessage(monitorVo.getVisitId(), JSONUtil.toJsonStr(monitorVo));
//                        AsyncManager.me().execute(BusinessFactory.recordMonitorInfo(monitorVo));


                        List<NoticeMessageVo> noticeMessageVos = new ArrayList<>();
                        //判断设备是否异常
                        if (MonitorTypeEnum.TYPE_FF.getCode().equals(msgType)) {
                            NoticeMessageVo noticeMessageVo = new NoticeMessageVo();
                            noticeMessageVo.setMsgId(IdUtils.nextId());
                            noticeMessageVo.setMsgType(NoticeTypeEnum.TYPE_03.getCode());
                            noticeMessageVo.setMsgContent("设备传感器没接/断开，请尽快处理");
                            noticeMessageVos.add(noticeMessageVo);
                        } else if (MonitorTypeEnum.TYPE_00.getCode().equals(msgType)) {
                            NoticeMessageVo noticeMessageVo = new NoticeMessageVo();
                            noticeMessageVo.setMsgId(IdUtils.nextId());
                            noticeMessageVo.setMsgType(NoticeTypeEnum.TYPE_04.getCode());
                            noticeMessageVo.setMsgContent("设备传感器短路，请尽快处理");
                            noticeMessageVos.add(noticeMessageVo);
                        }

                        //判断温度
                        if (temperature > 37.2) {
                            NoticeMessageVo noticeMessageVo = new NoticeMessageVo();
                            noticeMessageVo.setMsgId(IdUtils.nextId());
                            noticeMessageVo.setMsgType(NoticeTypeEnum.TYPE_01.getCode());
                            noticeMessageVo.setMsgContent("体温偏高，请尽快处理");
                            noticeMessageVos.add(noticeMessageVo);
                        }

                        //判断电量
                        if (electricity < 10) {
                            NoticeMessageVo noticeMessageVo = new NoticeMessageVo();
                            noticeMessageVo.setMsgId(IdUtils.nextId());
                            noticeMessageVo.setMsgType(NoticeTypeEnum.TYPE_02.getCode());
                            noticeMessageVo.setMsgContent("电池电量低，请尽快处理");
                            noticeMessageVos.add(noticeMessageVo);
                        }

                        if (noticeMessageVos.size() > 0) {
                            for (NoticeMessageVo noticeMessageVo : noticeMessageVos) {
                                noticeMessageVo.setVisitId(bizPatientDeviceInfo.getVisitId());
                                noticeMessageVo.setMsgDate(new Date());
                                ConcurrentHashMap<String, Set<String>> concurrentHashMap = NoticeWebSocketServer.getUserMap();
                                for (String key : concurrentHashMap.keySet()) {
                                    NoticeWebSocketServer.sendSelfMessage(key, JSONUtil.toJsonStr(noticeMessageVo));
                                }

                                AsyncManager.me().execute(BusinessFactory.recordNoticeInfo(noticeMessageVo));
                            }
                        }

                    }

                }
            }
        };
    }
}
